﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace Grafica3
{
    public class SkyBox
    {
        private VertexBuffer box_vertices;
        private IndexBuffer box_indices;
        private Effect box_effect;
        GraphicsDevice GraphicsDevice;
        private readonly float diag = (float)Math.Sqrt(3);


        public SkyBox(GraphicsDevice GraphicsDevice, ContentManager Content, Effect effect)
        {
            this.GraphicsDevice = GraphicsDevice;
            box_effect = effect.Clone();
            box_effect.Parameters["BoxTexture"].SetValue(Content.Load<TextureCube>("Earth"));
            box_vertices = new VertexBuffer(GraphicsDevice, VertexPositionNormalTexture.VertexDeclaration, 8, BufferUsage.WriteOnly);
            box_indices = new IndexBuffer(GraphicsDevice, IndexElementSize.ThirtyTwoBits, 6 * 6, BufferUsage.WriteOnly);
            var vertices = new VertexPositionNormalTexture[8];
            for (int i = 0; i < 2; i++)
                for (int j = 0; j < 2; j++)
                    for (int l = 0; l < 2; l++)
                    {
                        var P = new Vector3(i * 2.0f - 1.0f, j * 2.0f - 1.0f, l * 2.0f - 1.0f);
                        var N = Vector3.Normalize(P);
                        var UV = new Vector2((float)Math.Atan2(P.Z, P.X) / 6.28f, 1.0f - j);
                        vertices[i * 4 + j * 2 + l] = new VertexPositionNormalTexture(P, N, UV);
                    }
            box_vertices.SetData(vertices);
            box_indices.SetData(new[]{
                0, 2, 4, 2, 4, 6, 6, 4, 5, 6, 5, 7, 
                1, 3, 5, 3, 5, 7, 0, 1, 2, 1, 2, 3, 
                0, 1, 4, 1, 4, 5, 2, 3, 6, 3, 6, 7
            });
        }

        public void Draw(Camera camera)
        {
            box_effect.Parameters["World"].SetValue(Matrix.CreateScale(camera.FarPlane / diag) * Matrix.CreateTranslation(camera.position));
            box_effect.Parameters["View"].SetValue(camera.View);
            box_effect.Parameters["Projection"].SetValue(camera.Projection);
            box_effect.CurrentTechnique = box_effect.Techniques["SkyBoxTecnique"];

            box_effect.CurrentTechnique.Passes[0].Apply();

            GraphicsDevice.Indices = box_indices;
            GraphicsDevice.SetVertexBuffer(box_vertices);
            GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, box_vertices.VertexCount, 0,
                box_indices.IndexCount / 3);
        }
    }
}
